/*
 * $Id: str.h,v 1.10 2006-08-30 07:15:14 bacon Exp $
 */

#ifndef _XP_BAS_STR_H_
#define _XP_BAS_STR_H_

#include <xp/types.h>
#include <xp/macros.h>

#define XP_STR_LEN(x)  ((x)->size)
#define XP_STR_SIZE(x) ((x)->size + 1)
#define XP_STR_CAPA(x) ((x)->capa)
#define XP_STR_BUF(x)  ((x)->buf)
#define XP_STR_CHAR(x,idx) ((x)->buf[idx])

/* 
 * TYPE: xp_str_t
 *   Defines a dynamically resizable string object
 * 
 * DESCRIPTION:
 *   <xp_str_t> defines a string object that can be dynamically resized
 *   if necessary. The memory it reserves may be larger than the actual 
 *   string it holds. Every xp_str_xxx function requires a pointer to 
 *   an <xp_str_t> object.
 */
typedef struct xp_str_t xp_str_t;

struct xp_str_t
{
	xp_char_t* buf;
	xp_size_t size;
	xp_size_t capa;
	xp_bool_t __dynamic;
};

#ifdef __cplusplus
extern "C" {
#endif

/* 
 * FUNCTION: xp_str_open
 *   Opens a dynamic string object
 *
 * PARAMETERS:
 *   str - [in] XP_NULL or a pointer to statically declared xp_str_t variable
 *   capa - [in] initial buffer capa
 *
 * RETURNS:
 *   Pointer to the instantiated object on success, XP_NULL on failure
 *
 * SEE ALSO:
 *   <xp_str_close>
 */
xp_str_t* xp_str_open (xp_str_t* str, xp_size_t capa);

/* 
 * FUNCTION: xp_str_close
 *   Closes a dynamic string object
 * 
 * PARAMETERS:
 *   str - [in] a pointer to an initialized string object
 *
 * SEE ALSO:
 *   <xp_str_open>
 */
void xp_str_close (xp_str_t* str);

void xp_str_forfeit (xp_str_t* str);

/*
 * FUNCTION: xp_str_yield
 *   Detaches the internal buffer off the object and returns it.
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 *   capa - [in] new buffer capa 
 *
 * RETURNS:
 *   a pointer to the internal buffer on success, XP_NULL on failure
 *
 * DESCRIPTION:
 *   The internal buffer returned by <xp_str_yield> should be freed
 *   explicitly when its use is over. The string buffer is reconfigured
 *   with a buffer of new *capa*.
 *   
 * SEE ALSO: 
 *   <xp_str_yield>
 */
xp_char_t* xp_str_yield (xp_str_t* str, xp_size_t capa);

/*
 * FUNCTION: xp_str_cield
 *   Closes the string object yielding the internal buffer
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 *
 * RETURNS:
 *   a pointer to the internal buffer
 *
 * DESCRIPTION:
 *   <xp_str_cield> is equivalent to <xp_str_close> except that it does not 
 *   destroy the internal buffer but returns it instead. The returned buffer 
 *   should be freed explicitly when its use is over.
 * 
 * SEE ALSO:
 *   <xp_str_cield>
 */
xp_char_t* xp_str_cield (xp_str_t* str);

/*
 * FUNCTION: xp_str_len
 *   Returns the length of the string held in a string object
 * 
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 * 
 * RETURNS:
 *   Number of characters *str* is holding 
 *
 * SEE ALSO:
 *   <xp_str_size> <xp_str_capa> <xp_str_buf>
 */
xp_size_t xp_str_len (xp_str_t* str);

/*
 * FUNCTION: xp_str_size
 *   Returns the length of a string plus 1
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 * 
 * RETURNS:
 *   Number of characters + 1
 *
 * SEE ALSO:
 *   <xp_str_len> <xp_str_capa> <xp_str_buf>
 */
xp_size_t xp_str_size (xp_str_t* str);

/*
 * FUNCTION: xp_str_capa
 *   Returns the capacity of the internal buffer
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 * 
 * RETURNS:
 *   Maximum number of characters *str* can hold
 *
 * SEE ALSO:
 *   <xp_str_len> <xp_str_size> <xp_str_buf>
 */
xp_size_t xp_str_capa (xp_str_t* str);

/*
 * FUNCTION: xp_str_buf
 *   Returns the string buffer
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 * 
 * RETURNS:
 *   Pointer to the internal string buffer
 *
 * SEE ALSO:
 *   <xp_str_len> <xp_str_size> <xp_str_capa>
 */
const xp_char_t* xp_str_buf (xp_str_t* str);

/* 
 * FUNCTION: xp_str_cpy 
 *   Copys a null-terminated string to a string object
 * 
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 *   s - [in] a null-terminated character string
 *
 * RETURNS: 
 *   Length of the null-terminated string copies excluding the terminating '\0'.
 *
 * SEE ALSO:
 *   <xp_str_cpyn>
 */
xp_size_t xp_str_cpy (xp_str_t* str, const xp_char_t* s);

/* 
 * FUNCTION: xp_str_ncpy
 *   Copys a length-bound string into a string object
 */
xp_size_t xp_str_ncpy (xp_str_t* str, const xp_char_t* s, xp_size_t len);

/* 
 * FUNCTION: xp_str_cpyn
 *   Copys a string into a string object
 *
 * PARAMETERS:
 *   str - [in out] a string object
 *   s - [in] a string
 *   n - [in] maximum number of characters to copy 
 *
 * RETURNS:
 *   Number of characters in the string object
 *
 * DESCRIPTION:
 *   <xp_str_cpyn> copies at most *n* characters of a string into the string
 *   object. If '\0' is found before the *n*-th character, it stops copying 
 *   characters and returns. Otherwise, it stops after it has copied the 
 *   *n*-th character.
 * 
 * SEE ALSO:
 *   <xp_str_cpy> <xp_str_ncpy> <xp_str_ccpy>
 */
xp_size_t xp_str_cpyn (xp_str_t* str, const xp_char_t* s, xp_size_t n);

/*
 * FUNCTION: xp_str_ccpy
 *   Copys a character into a string object
 */
xp_size_t xp_str_ccpy (xp_str_t* str, xp_char_t c);

/*
 * FUNCTION: xp_str_cat
 */
xp_size_t xp_str_cat (xp_str_t* str, const xp_char_t* s);

/*
 * FUNCTION: xp_str_ncat
 *
 * RETURNS:
 *   Size of *str* on success, (xp_size_t)-1 on failure
 */
xp_size_t xp_str_ncat (xp_str_t* str, const xp_char_t* s, xp_size_t len);

/*
 * FUNCTION: xp_str_catn
 */
xp_size_t xp_str_catn (xp_str_t* str, const xp_char_t* s, xp_size_t n);

/*
 * FUNCTION: xp_str_ccat
 */
xp_size_t xp_str_ccat (xp_str_t* str, xp_char_t c);

/*
 * FUNCTION: xp_str_nccat
 */
xp_size_t xp_str_nccat (xp_str_t* str, xp_char_t c, xp_size_t len);

/*
 * FUNCTION: xp_str_del
 *   Deletes part of a string 
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 *   pos - [in] the position of the first character to delete
 *   n - [in] the number of characters to delete
 *
 * RETURNS:
 *   Length of the string after deletion
 *
 * SEE ALSO:
 *   <xp_str_clear>
 */
xp_size_t xp_str_del (xp_str_t* str, xp_size_t pos, xp_size_t n);

/*
 * FUNCTION: xp_str_clear
 *   Deletes all characters of a string
 *
 * PARAMETERS:
 *   str - [in] a pointer to a string object
 * 
 * DESCRIPTION:
 *   <xp_str_clear> deletes all characters contained in *str* and makes the
 *   length 0.
 * 
 * SEE ALSO:
 *   <xp_str_del>
 */
void xp_str_clear (xp_str_t* str);

#ifdef __cplusplus
}
#endif

#endif
